package com.tianxiabuyi.weixin.qy.media;


import com.alibaba.fastjson.annotation.JSONField;
import com.tianxiabuyi.utils.JSONUtil;
import com.tianxiabuyi.weixin.common.WxClient;
import com.tianxiabuyi.weixin.common.exception.WxRuntimeException;
import com.tianxiabuyi.weixin.common.media.MediaType;
import com.tianxiabuyi.weixin.common.media.MpNews;
import com.tianxiabuyi.weixin.common.media.bean.Counts;
import com.tianxiabuyi.weixin.common.media.bean.MaterialPagination;
import com.tianxiabuyi.weixin.common.media.bean.MpNewsPagination;
import com.tianxiabuyi.weixin.qy.QyWxClientFactory;

import java.io.File;
import java.util.*;
/**
 * 永久素材管理
 *
 */
public class Materials {


    private WxClient wxClient;
    /**
     * 初始化wxclient
     * @param corpId
     * @param corpSecret
     * @return
     */
    public static Materials with(String corpId, String corpSecret) {
        Materials materials = new Materials();
        materials.setWxClient(QyWxClientFactory.getInstance().with(corpId, corpSecret));
        return materials;
    }

    /**
     * 设置wxclient，如果已使用with初始化，则不用调用该方法
     * @param wxClient
     */
    public void setWxClient(WxClient wxClient) {
        this.wxClient = wxClient;
    }

    /**
     * 添加mpnews素材
     * @param mpNews
     * @return
     */
    public String addMpNews(MpNews mpNews) {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/material/add_mpnews";
        Map<String, Object> request = new HashMap<>();
        request.put("mpnews", mpNews);
        String json = JSONUtil.toJson(request);
        String response =  wxClient.post(url, json);
        System.out.println(response);
        Map<String, Object> result = JSONUtil.fromJson(response, Map.class);
        if (result.containsKey("media_id")) {
            return result.get("media_id").toString();
        } else {
            throw new WxRuntimeException(999, response);
        }
    }

    /**
     * 更新mpnews素材
     * @param mediaId
     * @param mpNews
     */
    public void updateMpNews(String mediaId, MpNews mpNews) {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/material/update_mpnews";
        Map<String, Object> request = new HashMap<>();
        request.put("mpnews", mpNews);
        request.put("mediaId", mediaId);
        String json = JSONUtil.toJson(request);
        wxClient.post(url, json);
    }

    /**
     * 根据mediaid获取mpnews
     * @param mediaId
     * @return
     */
    public MpNews getMpNews( String mediaId) {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/material/get?media_id=%s";
        String response = wxClient.get(String.format(url,  mediaId));
        GetMpNewsResponse getMpNewsResponse = JSONUtil.fromJson(response, GetMpNewsResponse.class);
        if (getMpNewsResponse != null) {
            return getMpNewsResponse.getMpNews();
        } else {
            return null;
        }
    }

    /**
     * 根据mpnews删除mediaid
     * @param mediaId
     */
    public void deleteMpNews(String mediaId) {
        delete(mediaId);
    }

    /**
     * 删除文件素材
     * @param type 文件类型
     * @param fileName  文件路径
     * @return
     */
    public String upload(MediaType type,  String fileName) {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?type=%s";
        String response = wxClient.upload(  fileName, String.format(url, type.name()));
        Map<String, Object> result = JSONUtil.fromJson(response, Map.class);
        if (result.get("media_id") != null) {
            return result.get("media_id").toString();
        } else {
            throw new WxRuntimeException(998, response);
        }
    }

    /**
     * 根据mediaid下载文件
     * @param mediaId
     * @return
     */
    public File download(String mediaId) {
        return wxClient.download(String.format("https://qyapi.weixin.qq.com/cgi-bin/media/get?media_id=%s",  mediaId));
    }

    /**
     * 根据mediaid删除素材
     * @param mediaId
     */
    public void delete(String mediaId) {
        String response = wxClient.get(String.format("https://qyapi.weixin.qq.com/cgi-bin/material/del?media_id=%s", mediaId));
    }


    /**
     * 获取当前素材总量
     * @return
     */
    public Counts count() {
        String response = wxClient.get(String.format("https://qyapi.weixin.qq.com/cgi-bin/material/get_count" ));
        return JSONUtil.fromJson(response, Counts.class);
    }

    /**
     * 获取当前管理组指定类型的素材列表
     * @param type  指定文件类型
     * @param offset 从该类型素材的该偏移位置开始返回，0表示从第一个素材 返回
     * @param size   返回素材的数量，取值在1到50之间
     * @return
     */
    public MaterialPagination list( MediaType type, int offset, int size) {
        String request = "{\"type\":\"%s\",\"offset\":%s,\"count\":%s}";
        String url = "https://qyapi.weixin.qq.com/cgi-bin/material/batchget";
        String response = wxClient.post(url, String.format(request, type.name(),  offset, size));

        return toMaterialSearchResult(JSONUtil.fromJson(response, QyMaterialSearchResult.class));
    }

    /**
     * 获取当前管理组mpnews的素材列表
     * @param offset 从该类型素材的该偏移位置开始返回，0表示从第一个素材 返回
     * @param size 返回素材的数量，取值在1到50之间
     * @return
     */
    public MpNewsPagination listMpNews( int offset, int size) {
        String request = "{\"type\":\"%s\",\"offset\":%s,\"count\":%s}";
        String url = "https://qyapi.weixin.qq.com/cgi-bin/material/batchget";
        String response = wxClient.post(url, String.format(request, MediaType.mpnews.name(),  offset, size));


        return JSONUtil.fromJson(response, MpNewsPagination.class);
    }

    private MaterialPagination toMaterialSearchResult(QyMaterialSearchResult qyMaterialSearchResult) {
        MaterialPagination result = new MaterialPagination();
        result.setTotalCount(qyMaterialSearchResult.getTotalCount());
        result.setCurrentCount(qyMaterialSearchResult.getCurrentCount());

        List<QyMaterialSearchResult.Material> qyItems = qyMaterialSearchResult.getItems();
        List<MaterialPagination.Material> items = new ArrayList<>();

        for (QyMaterialSearchResult.Material qyItem : qyItems) {
            MaterialPagination.Material item = new MaterialPagination.Material();
            item.setFileName(qyItem.getFileName());
            item.setMediaId(qyItem.getMediaId());
            item.setUpdateTime(qyItem.updateTime);

            items.add(item);
        }
        result.setItems(items);
        return result;
    }

    public static class QyMaterialSearchResult {

        private MediaType type;

        @JSONField(name = "total_count")
        private int totalCount;

        @JSONField(name = "item_count")
        private int currentCount;

        @JSONField(name = "itemlist")
        private List<Material> items;

        public MediaType getType() {
            return type;
        }

        public void setType(MediaType type) {
            this.type = type;
        }

        public int getTotalCount() {
            return totalCount;
        }

        public void setTotalCount(int totalCount) {
            this.totalCount = totalCount;
        }

        public int getCurrentCount() {
            return currentCount;
        }

        public void setCurrentCount(int currentCount) {
            this.currentCount = currentCount;
        }

        public List<Material> getItems() {
            return items;
        }

        public void setItems(List<Material> items) {
            this.items = items;
        }

        public static class Material {

            @JSONField(name = "media_id")
            private String mediaId;

            @JSONField(name = "filename")
            private String fileName;

            @JSONField(name = "update_time")
            private Date updateTime;

            public String getMediaId() {
                return mediaId;
            }

            public void setMediaId(String mediaId) {
                this.mediaId = mediaId;
            }

            public String getFileName() {
                return fileName;
            }

            public void setFileName(String fileName) {
                this.fileName = fileName;
            }

            public Date getUpdateTime() {
                return updateTime;
            }

            public void setUpdateTime(Date updateTime) {
                this.updateTime = updateTime;
            }
        }
    }

    public static class GetMpNewsResponse {

        private String type;

        @JSONField(name = "mpnews")
        private MpNews mpNews;

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public MpNews getMpNews() {
            return mpNews;
        }

        public void setMpNews(MpNews mpNews) {
            this.mpNews = mpNews;
        }
    }
}
